package org.hackystat.devcathlon.engine.user;

import java.io.Serializable;

import org.hackystat.devcathlon.engine.profile.Profile;

/**
 * A devcathlon user, who must also be a registered Hackystat user.
 * This class stores user profile information.
 * The email and password must be legal credentials for the sensorbase associated with this
 * Devcathlon instance.   
 * @author Philip Johnson
 */
public class User implements Serializable, Comparable<User> {
  /** Support serialization. */
  private static final long serialVersionUID = 1L;
  /** The primary key. */
  private Long id;
  /** The first name of this user. */
  private String firstName;
  /** The last name of this user. */
  private String lastName;
  /** The email for this user, also their Hackystat account. */
  private String email;
  /** The hackystat password for this user. */
  private String password;
  /** The  username. */
  private String username;
  /** The user profile. */
  private Profile profile;

  /**
   * User default constructor.
   */
  public User() {
    // empty constructor.
  }
  
  /**
   * Creates a new user. Typically done by the UserManager.  
   * @param firstName The first name. 
   * @param lastName The last name. 
   * @param email The email. 
   * @param password The password. 
   */
  User(String firstName, String lastName, String email, String password) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.password = password;
  }
  
  /**
   * Returns the unique id.
   * 
   * @return the id
   */
  public Long getId() {
    return id;
  }

  /**
   * Sets the unique id.
   * 
   * @param id the id to set
   */
  protected void setId(Long id) {
    this.id = id;
  }

  /**
   * Return the first name of this user. 
   * @return The first name. 
   */
  public String getFirstName() {
    return this.firstName;
  }

  
  /**
   * Sets the first name of this user.
   * 
   * @param firstName the firstName to set
   */
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  /**
   * Return the last name of this user. 
   * @return The last name. 
   */
  public String getLastName() {
    return this.lastName;
  }

  /**
   * Sets the user last name.
   * 
   * @param lastName the lastName to set
   */
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  
  /**
   * Returns the user's first and last names.
   * 
   * @return The user's first and last names.
   */
  public String getFullName() {
    return firstName + " " + lastName;
  }

  /**
   * Return the email (Hackystat account) for this user. 
   * @return The email.
   */
  public String getEmail() {
    return this.email;
  }

  /**
   * Sets the user email.
   * 
   * @param email the email to set
   */
  public void setEmail(String email) {
    this.email = email;
  }

  /**
   * Return the Hackystat password of this user. 
   * @return The password.
   */
  public String getPassword() {
    return this.password;
  }
  
  /**
   * Sets the user password.
   * 
   * @param password the password to set
   */
  public void setPassword(String password) {
    this.password = password;
  }

  /**
   * Returns the username. 
   * 
   * @return the username
   */
  public String getUsername() {
    return username;
  }

  /**
   * Sets the username.
   * 
   * @param username the username to set
   */
  public void setUsername(String username) {
    this.username = username;
  }

  /**
   * Returns the profile.
   * 
   * @return the profile
   */
  public Profile getProfile() {
    return profile;
  }

  /**
   * Sets the profile.
   * 
   * @param profile the profile to set
   */
  public void setProfile(Profile profile) {
    this.profile = profile;
  }

  /**
   * Updates the user's credentials.  Required if user was invited
   * before he joined Devcathlon system.
   * @param email The user's email.
   * @param password The user's password.
   */
  public void updateCredentials(String email, String password) {
    this.email = email;
    this.password = password;
  }

  /**
   * Sets the class to have natural sorting order by last name.
   * @param user The user to compare.
   * @return A negative if less than, positive if greater.
   */
  public int compareTo(User user) {
    return this.lastName.compareTo(user.getLastName());
  }  
  
  /** 
   * Compares any object and returns true if equals.
   * @param obj The object to compare
   * @return The boolean if object is equal.
   */
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof User)) {
      return false;
    }
    if (!(this.email.equals(((User)obj).getEmail()))) {
      return false;
    }
    if (!(this.firstName.equals(((User)obj).getFirstName()))) {
      return false;
    }
    if (!(this.lastName.equals(((User)obj).getLastName()))) {
      return false;
    }
    if (!(this.password.equals(((User)obj).getPassword()))) {
      return false;
    }
    return true;
  }
  
  /**
   *  Generic override, likely won't be used.  Needed because equals() was override.
   *  @return The hash code value.
   */
  public int hashCode() {
    assert false : "hashCode not designed";
    return 42; // any arbitrary constant will do
//    return email.hashCode();
  }

}
